package Server.ExtComponents.socket;

import Server.ExtComponents.BaseConfig.MServerConfig;
import Server.ServerCore.Model.Player.PlayerInstance;
import Server.ServerCore.Service.Logic.ProcessSession;
import Server.ServerCore.Service.service.PlayerManagerService;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.*;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author :石头哥哥<br/>
 *         Project:myFrameServer
 *         Date: 13-4-27
 *         Time: 下午9:07
 *         SimpleChannelUpstreamHandler  messageReceived
 *         FrameDecoder   messageReceived---->>decode
 */
@Deprecated
public class MServerUpstreamHandler extends SimpleChannelUpstreamHandler {

    private static final Logger LOG = LoggerFactory.getLogger(MServerFrameHandler.class);
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    private ObjectSession objectSession=null;
    private ProcessSession processSession=null;
    private PlayerInstance player=null;

    /**记录服务器在线人数*/
    public static final AtomicInteger countConnection=new AtomicInteger(0);

    private int lengthFieldLength;

    public MServerUpstreamHandler(int lengthFieldLength){
        this.lengthFieldLength=lengthFieldLength;
    }
    /**
     * Invoked when a message object (e.g: {@link org.jboss.netty.buffer.ChannelBuffer}) was received
     * from a remote peer.
     */
    public void messageReceived(
            ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        Object m = e.getMessage();
        if (!(m instanceof ChannelBuffer)) {
            ctx.sendUpstream(e);
            return;
        }
        ChannelBuffer inboundBuffer = (ChannelBuffer) m;
        if (!inboundBuffer.readable()) {
            return;
        }

        if (inboundBuffer.readableBytes() < this.lengthFieldLength) {
            return;
        }
        //
        int actualLength =  inboundBuffer.getUnsignedShort(inboundBuffer.readerIndex());
        //可读字节数小于一个完整的包，等待下一次读事件
        if (inboundBuffer.readableBytes()<actualLength+  this.lengthFieldLength){
            return ;
        }
        inboundBuffer.skipBytes( this.lengthFieldLength);// 跳过包长占字节数2
        int index=inboundBuffer.readerIndex();
        ChannelBuffer dataBuf=extractFrame(inboundBuffer,index,actualLength);

        //Sets the  readerIndex of this inboundBuffer.
        inboundBuffer.readerIndex(index+actualLength);

        //logic handle
        if (dataBuf!=null)
            this.objectSession.getHandBuffers().add(dataBuf);
//        this.processSession.setBuffer(dataBuf);

        ((ExecutionHandler) ctx.getPipeline().get("executor")).getExecutor().execute(this.processSession);
    }


    protected ChannelBuffer extractFrame(ChannelBuffer buffer, int index, int length) {
        ChannelBuffer frame = ChannelBuffers.buffer(length);
        frame.writeBytes(buffer, index, length);
        return frame;
    }

    @Override
    public void channelConnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {

        Channel channel=e.getChannel();

        countConnection.incrementAndGet();
        this.objectSession=new ObjectSession(channel);//创建一个MSession

        this.processSession=new ProcessSession(this.objectSession);
        /**
         * 注册player的session
         */
        player=new PlayerInstance(this.objectSession);

        PlayerManagerService.SESSION_PLAYER_INSTANCE_MAP.put(this.objectSession,player);
        ctx.sendUpstream(e);
        if(MServerConfig.NETTY_DEBUG)LOG.info("Concurrent  connection... " +countConnection.get());
    }

    @Override
    public void channelClosed(
            ChannelHandlerContext ctx, ChannelStateEvent e){
        try{
            DestroySession(ctx);
            ctx.sendUpstream(e);
        }catch (Exception ee){
            LOG.warn("close channel error!",ee);
        }
    }

    @Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        ctx.getChannel().close();
        ctx.sendUpstream(e);
    }

    private void  DestroySession(ChannelHandlerContext ctx){
        /**保存角色数据*/
        PlayerManagerService.SESSION_PLAYER_INSTANCE_MAP.get(this.objectSession).save();
        PlayerManagerService.SESSION_PLAYER_INSTANCE_MAP.remove(this.objectSession) ;
        this.objectSession.Destroy();
        this.objectSession=null;
        this.processSession=null;
        this.player=null;
        MServerFrameUtil.clearPipeline(ctx.getPipeline());
        if (MServerConfig.NETTY_DEBUG)LOG.info("channelClosed， Concurrent  connection... " +countConnection.decrementAndGet());
    }


    public ObjectSession getmSession() {
        return this.objectSession;
    }

}
